package tx.service;

import org.springframework.stereotype.Service;
import tx.dao.UserDao;

/**
 * https://www.cnblogs.com/jhxxb/p/10450944.html
 * 当事务方法被另一个事务方法调用时，必须指定事务应该如何传播，列如方法可能继续在现有事务中运行，也可能开启一个新事务，
 * 并在自己的事务中运行，事务传播的行为有传播属性指定，Spring 定义了 7 中类传播行为
 * <p>
 * REQUIRED         如果有事务在运行，当前的方法就在这个事务内运行，否则就启动一个新的事务，并在自己的事务内运行
 * REQUIRED_NEW     当前方法必须启动事务，并在它自己的事务内运行，如果有事务正在运行，应该将他挂起
 * SUPPORTS         如果有事务在运行，当前的方法就在这个事务内运行，否则他可以不运行在事务中
 * NOT_SUPPORTE     当前的方法不应该运行在事务中，如果有运行的事务，将他挂起
 * MANDATORY        当前的方法必须运行在事务内部，如果没有正在运行的事务，就抛出异常
 * NEVER            当前方法不应该运行在事务中，如果有运行的事务，就抛出异常
 * NESTED           如果有事务在运行，当前的方法就应该在这个事物的嵌套事务内运行，否则，就启动一个新的事务，并在它自己的事务内运行
 * 事务传播属性可以在 @Transactional 注解的 propagation 属性中定义
 * <pre>
 * 事务的属性：
 * 	1.★propagation：用来设置事务的传播行为
 * 		事务的传播行为：一个方法运行在了一个开启了事务的方法中时，当前方法是使用原来的事务还是开启一个新的事务
 * 		-Propagation.REQUIRED：默认值，使用原来的事务
 * 		-Propagation.REQUIRES_NEW：将原来的事务挂起，开启一个新的事务
 * 	2.★isolation：用来设置事务的隔离级别
 * 		-Isolation.REPEATABLE_READ：可重复读，MySQL 默认的隔离级别
 * 		-Isolation.READ_COMMITTED：读已提交，Oracle 默认的隔离级别，开发时通常使用的隔离级别
 * </pre>
 */
@Service
public class UserService {

    private final UserDao userDao;

    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }

    // @Transactional
    public void insertUser() {
        userDao.insert();
        System.out.println("插入完成...");
        insertUser2();
    }

    // @Transactional
    public void insertUser2() {
        userDao.insert();
        System.out.println("插入完成...");
        int i = 10 / 0;
    }
}
